package com.jcfk.system.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jcfk.common.business.service.BaseService;
import com.jcfk.common.core.utils.BeanUtils;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.common.web.domain.DataPage;
import com.jcfk.common.web.domain.RetResult;
import com.jcfk.system.dao.SysRoleDao;
import com.jcfk.system.domain.dto.SysRoleDTO;
import com.jcfk.system.domain.po.RefUserRoleMapping;
import com.jcfk.system.domain.po.SysRole;
import com.jcfk.system.domain.query.SysRoleQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.jcfk.common.core.utils.BeanUtils.convertList;

/**
 * 角色管理
 */
@Service
public class SysRoleService extends BaseService<SysRoleDao, SysRole> {


    @Autowired
    private RefUserRoleMappingService refUserRoleMappingService;

    /**
     * 根据条件获取用户分页列表
     *
     * @param page  分页设置
     * @param query 查询条件
     * @return 分页查询结果
     */
    public DataPage<SysRoleDTO> queryByPage(DataPage<SysRoleDTO> page, SysRoleQuery query) {
        // 分页查询
        return this.baseMapper.queryByPage(page, query);
    }

    /**
     * 根据条件获取用户分页列表
     *
     * @param query 查询条件
     * @return 分页查询结果
     */
    public List<SysRoleDTO> queryByPage(SysRoleQuery query) {
        // 分页查询
        return this.baseMapper.queryByPage(query);
    }

    /**
     * 根据条件获取用户信息列表
     *
     * @param query 查询条件
     * @return List<SysUserDTO>
     */
    public List<SysRoleDTO> getList(SysRoleQuery query) {
        // 查询条件
        QueryWrapper<SysRole> qw = new QueryWrapper<>();
        if (!StrUtil.isEmpty(query.getRoleName())) {
            qw.lambda().eq(SysRole::getRoleName, query.getRoleName());
        }

        if (query.getEnabled() != null) {
            qw.lambda().eq(SysRole::getEnabled, query.getEnabled());
        }
        qw.lambda().eq(SysRole::getDeleted, 0).eq(SysRole::getEnabled, 1);
        // 查询数据
        List<SysRole> list = super.list(qw);
        List<SysRoleDTO> dtoList = new ArrayList<>();
        for (SysRole po : list) {
            SysRoleDTO dto = new SysRoleDTO();
            BeanUtils.copyProperties(po, dto);

            dtoList.add(dto);
        }
        return dtoList;
    }


    /**
     * 判断角色是已经存在
     *
     * @param dto
     * @return
     */
    public RetResult<String> isValid(SysRoleDTO dto) {

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_name", dto.getRoleName()).eq("deleted", 0);

        if (!StringUtils.isEmpty(dto.getId())) queryWrapper.ne("id", dto.getId());
        Integer count = this.count(queryWrapper);

        if (count > 0) return RetResult.fail("角色名称已存在");

        return RetResult.ok();
    }

    /**
     * 添加角色
     *
     * @param dto
     * @return
     */
    public SysRoleDTO insert(SysRoleDTO dto) {
        dto.setVersion(1L);
        this.setDefaultValue(dto);
        // 实体
        SysRole role = new SysRole();
        BeanUtils.copyProperties(dto, role);

        this.save(role);
        BeanUtils.copyProperties(role, dto);

        return dto;
    }

    /**
     * 修改角色
     *
     * @param dto
     * @return
     */
    public SysRoleDTO update(SysRoleDTO dto) {
        this.setDefaultValue(dto);
        // 实体
        SysRole role = new SysRole();
        BeanUtils.copyProperties(dto, role);

        this.updateById(role);
        BeanUtils.copyProperties(role, dto);

        return dto;
    }


    /**
     * 根据主键删除用户(逻辑删除)
     *
     * @param dto
     * @return bool
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean logicDeleteList(SysRoleDTO dto) {

        SysRole role = new SysRole();
        role.setDeleted(1);

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", dto.getIds());

        QueryWrapper<RefUserRoleMapping> refUserRoleMappingUpdateWrapper = new QueryWrapper<>();
        refUserRoleMappingUpdateWrapper.in("role_id", dto.getIds());
        refUserRoleMappingService.remove(refUserRoleMappingUpdateWrapper);
        return this.update(role, queryWrapper);
    }

    /**
     * 根据主键获取角色信息
     *
     * @param id 主键
     * @return StandardCodeDTO
     */
    public SysRoleDTO get(String id) {
        // 查询数据
        SysRole item = this.baseMapper.selectById(id);
        SysRoleDTO dto = new SysRoleDTO();
        try {
            BeanUtils.copyProperties(item, dto);
        } catch (RuntimeException e) {
            throw e;
        }
        return dto;
    }


    /**
     * 获取所有可用角色
     *
     * @return StandardCodeDTO
     */
    public List<SysRoleDTO> listAll() {

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0).eq("enabled", 1);

        List<SysRole> roles = this.list(queryWrapper);

        return convertList(roles, SysRoleDTO.class);
    }


    /**
     * 设置添加默认值
     *
     * @param dto 添加对象
     */
    public void setDefaultValue(SysRoleDTO dto) {
        if (StrUtil.isEmpty(dto.getCreatedUserId())) {
            dto.setCreatedUserId(SecurityUtils.getUserId());
            dto.setCreatedUserName(SecurityUtils.getUserName());
            dto.setCreateTime(new Date());
            dto.setDeleted(0);
        }
        dto.setLastUpdatedUserId(SecurityUtils.getUserId());
        dto.setLastUpdateTime(new Date());
        dto.setLastUpdatedUserName(SecurityUtils.getUserName());
    }

    /**
     * 设置添加默认值
     *
     * @param dto 添加对象
     */
    public void setDefaultValue(SysRole dto) {
        dto.setLastUpdatedUserId(SecurityUtils.getUserId());
        dto.setLastUpdateTime(new Date());
        dto.setLastUpdatedUserName(SecurityUtils.getUserName());
        dto.setDeleted(0);
    }

}
